//! Digital IO Implementations
//!
//! For a detailed explanation, refer to the [general Digital IO documentation][1].
//!
//! [1]: ../../avr_hal_generic/port/index.html

pub use avr_hal_generic::port::mode;

pub trait PortExt {
    type Parts;

    fn split(self) -> Self::Parts;
}

avr_hal_generic::impl_generic_pin! {
    pub enum Pin {
        A(crate::pac::PORTA, porta, pina, ddra),
        B(crate::pac::PORTB, portb, pinb, ddrb),
        C(crate::pac::PORTC, portc, pinc, ddrc),
        D(crate::pac::PORTD, portd, pind, ddrd),
        E(crate::pac::PORTE, porte, pine, ddre),
        F(crate::pac::PORTF, portf, pinf, ddrf),
        G(crate::pac::PORTG, portg, ping, ddrg),
    }
}

avr_hal_generic::impl_port! {
    pub mod porta {
        #[port_ext]
        use super::PortExt;

        #[generic_pin]
        use Pin::A;

        impl PortExt for crate::pac::PORTA {
            regs: (pina, ddra, porta),
            pa0: (PA0, 0),
            pa1: (PA1, 1),
            pa2: (PA2, 2),
            pa3: (PA3, 3),
            pa4: (PA4, 4),
            pa5: (PA5, 5),
            pa6: (PA6, 6),
            pa7: (PA7, 7),
        }
    }
}

avr_hal_generic::impl_port! {
    pub mod portb {
        #[port_ext]
        use super::PortExt;

        #[generic_pin]
        use Pin::B;

        impl PortExt for crate::pac::PORTB {
            regs: (pinb, ddrb, portb),
            pb0: (PB0, 0),
            pb1: (PB1, 1),
            pb2: (PB2, 2),
            pb3: (PB3, 3),
            pb4: (PB4, 4),
            pb5: (PB5, 5),
            pb6: (PB6, 6),
            pb7: (PB7, 7),
        }
    }
}

avr_hal_generic::impl_port! {
    pub mod portc {
        #[port_ext]
        use super::PortExt;

        #[generic_pin]
        use Pin::C;

        impl PortExt for crate::pac::PORTC {
            regs: (pinc, ddrc, portc),
            pc0: (PC0, 0),
            pc1: (PC1, 1),
            pc2: (PC2, 2),
            pc3: (PC3, 3),
            pc4: (PC4, 4),
            pc5: (PC5, 5),
            pc6: (PC6, 6),
            pc7: (PC7, 7),
        }
    }
}

avr_hal_generic::impl_port! {
    pub mod portd {
        #[port_ext]
        use super::PortExt;

        #[generic_pin]
        use Pin::D;

        impl PortExt for crate::pac::PORTD {
            regs: (pind, ddrd, portd),
            pd0: (PD0, 0),
            pd1: (PD1, 1),
            pd2: (PD2, 2),
            pd3: (PD3, 3),
            pd4: (PD4, 4),
            pd5: (PD5, 5),
            pd6: (PD6, 6),
            pd7: (PD7, 7),
        }
    }
}

avr_hal_generic::impl_port! {
    pub mod porte {
        #[port_ext]
        use super::PortExt;

        #[generic_pin]
        use Pin::E;

        impl PortExt for crate::pac::PORTE {
            regs: (pine, ddre, porte),
            pe0: (PE0, 0),
            pe1: (PE1, 1),
            pe2: (PE2, 2),
            pe3: (PE3, 3),
            pe4: (PE4, 4),
            pe5: (PE5, 5),
            pe6: (PE6, 6),
            pe7: (PE7, 7),
        }
    }
}

avr_hal_generic::impl_port! {
    pub mod portf {
        #[port_ext]
        use super::PortExt;

        #[generic_pin]
        use Pin::F;

        impl PortExt for crate::pac::PORTF {
            regs: (pinf, ddrf, portf),
            pf0: (PF0, 0),
            pf1: (PF1, 1),
            pf2: (PF2, 2),
            pf3: (PF3, 3),
            pf4: (PF4, 4),
            pf5: (PF5, 5),
            pf6: (PF6, 6),
            pf7: (PF7, 7),
        }
    }
}

avr_hal_generic::impl_port! {
    pub mod portg {
        #[port_ext]
        use super::PortExt;

        #[generic_pin]
        use Pin::G;

        impl PortExt for crate::pac::PORTG {
            regs: (ping, ddrg, portg),
            pg0: (PG0, 0),
            pg1: (PG1, 1),
            pg2: (PG2, 2),
            pg3: (PG3, 3),
            pg4: (PG4, 4),
        }
    }
}